<script setup lang="tsx">
import { ref } from 'vue';
import type { Ref } from 'vue';
import { NButton, NPopconfirm, NTag, NTreeSelect } from 'naive-ui';
import { useBoolean } from '@sa/hooks';
import { useAppStore } from '@/store/modules/app';
import { useTable, useTableOperate } from '@/hooks/common/table';
import { $t } from '@/locales';
import { yesOrNoRecord } from '@/constants/common';
import SvgIcon from '@/components/custom/svg-icon.vue';
import { fetchGetGroups, addGroup, editGroup, deleteGroup } from '@/service/api/group';
import { fetchGetUserRoutes } from '@/service/api/route';

const appStore = useAppStore();

const { bool: visible, setTrue: openModal } = useBoolean();

const wrapperRef = ref<HTMLElement | null>(null);
const title = ref('');
const rulesTree = ref<any[]>([]);
const rulesLoading = ref(false);

const model = ref<Partial<GroupApi.Group & { rulesArray: (string | number)[] }>>({
    id: 0,
    name: '',
    rules: '',
    status: 'normal',
    rulesArray: []
});
const rules = {};

const { columns, columnChecks, data, loading, pagination, getData, getDataByPage } = useTable({
    apiFn: fetchGetGroups,
    columns: () => [
        {
            key: 'id',
            title: 'ID',
            align: 'center',
            width: 100,
        },
        {
            key: 'name',
            title: '权限组名称',
            align: 'center',
            width: 250,
        },
        {
            key: 'rules',
            title: '规则ID',
            align: 'center',
            width: 300,
        },
        {
            key: 'createtime',
            title: '创建时间',
            align: 'center',
            width: 200,
        },
        {
            key: 'updatetime',
            title: '更新时间',
            align: 'center',
            width: 200,
        },
        {
            key: 'status',
            title: '状态',
            align: 'center',
            width: 120,
            render: (row) => {
                const status: CommonType.YesOrNo = row.status === 'hidden' ? 'N' : 'Y';

                const tagMap: Record<CommonType.YesOrNo, NaiveUI.ThemeColor> = {
                    Y: 'error',
                    N: 'default'
                };

                const label = $t(yesOrNoRecord[status]);

                return <NTag type={ tagMap[status] }> { label } </NTag>;
            }
        },
        {
            key: 'operate',
            title: '操作',
            align: 'center',
            width: 230,
            render: (row) => (
                <div class= "flex-center justify-end gap-8px" >
                <NButton type="primary" ghost size="small" onClick={() => handleEdit(row)}>
                    编辑
                    </NButton>
                    < NPopconfirm onPositiveClick = {() => handleDelete(row.id as number)}>
                        {{
              default: () => '确定删除吗？',
        trigger: () => (
            <NButton type= "error" ghost size = "small" >
                删除
                </NButton>
              )
}}
</NPopconfirm>
    </div>
      )
    }
  ]
});

const { checkedRowKeys, onBatchDeleted, onDeleted } = useTableOperate(data, getData);

const operateType = ref('add');

function handleAdd() {
    operateType.value = 'add';
    title.value = '新增API权限组';
    // 清空model
    model.value = {
        id: 0,
        name: '',
        rules: '',
        status: 'normal',
        rulesArray: []
    };
    openModal();
}

async function handleDelete(id: number) {
    // request
    const { response } = await deleteGroup(id);
    console.log(response);
    if (response?.data?.code === 1) {
        window.$message?.success('删除成功！');
        getData();
    } else {
        window.$message?.error(response?.data?.msg || '删除失败');
    }
}

function handleEdit(item: any) {
    operateType.value = 'edit';
    title.value = '编辑API权限组';
    model.value = {
        id: item.id,
        name: item.name,
        rules: item.rules,
        status: item.status,
        rulesArray: rulesStrToArray(item.rules)
    };
    openModal();
}

function init() {
    initRulesTree();
}

// 创建获取规则树数据的函数
async function initRulesTree() {
    rulesLoading.value = true;
    try {
        const { response } = await fetchGetUserRoutes();
        if (response?.data?.code === 1) {
            // 假设接口返回的数据结构需要转换成tree格式
            rulesTree.value = formatRulesTree(response.data.data || []);
        } else {
            window.$message?.error(response?.data?.msg || '获取规则列表失败');
        }
    } catch (error) {
        console.error('获取规则列表失败', error);
        window.$message?.error('获取规则列表失败');
    } finally {
        rulesLoading.value = false;
    }
}

// 转换规则树数据格式的函数
function formatRulesTree(data: any[]) {
    // 根据实际API返回结构进行格式转换
    // 这里假设API返回的数据结构已经是合适的树形结构
    // 可能需要根据实际情况调整键名，如把id改为key，把name改为label等
    return data.map(item => ({
        key: item.id,
        label: item.title || item.name,
        children: item.children ? formatRulesTree(item.children) : undefined
    }));
}

// ID字符串转数组的函数
function rulesStrToArray(rulesStr: string): (string | number)[] {
    if (!rulesStr) return [];
    return rulesStr.split(',').map(item => {
        // 如果ID是数字类型，则转换为数字
        const numId = Number(item);
        return isNaN(numId) ? item : numId;
    });
}

// ID数组转字符串的函数
function rulesArrayToStr(rulesArray: (string | number)[]): string {
    if (!rulesArray || !rulesArray.length) return '';
    return rulesArray.join(',');
}

// init
init();

async function handleSubmit() {
    // 在提交前将规则数组转换为字符串
    if (model.value.rulesArray) {
        model.value.rules = rulesArrayToStr(model.value.rulesArray);
    }
    
    let res;
    if (operateType.value === 'add') {
        res = await addGroup(model.value);
    } else {
        res = await editGroup(model.value);
    }
    console.log('response: ', res.response);
    if (res.response?.data?.code === 1) {
        window.$message?.success(res.response.data.msg);
        visible.value = false;
        getData();
    } else {
        window.$message?.error(res.response?.data?.msg || '操作失败');
    }
}
</script>

<template>
    <div ref="wrapperRef" class="flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
        <NCard title="API权限组管理" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
            <template #header-extra>
                <TableHeaderOperation v-model:columns="columnChecks" :disabled-delete="checkedRowKeys.length === 0"
                    :loading="loading" @add="handleAdd" @refresh="getData" />
            </template>
            <NDataTable v-model:checked-row-keys="checkedRowKeys" :columns="columns" :data="data" size="small"
                :flex-height="!appStore.isMobile" :scroll-x="1088" :loading="loading" :row-key="row => row.id" remote
                :pagination="pagination" class="sm:h-full" />
        </NCard>
        <NModal v-model:show="visible" :title="title" preset="card" class="w-800px">
            <NScrollbar class="h-480px pr-20px">
                <NForm ref="formRef" :model="model" :rules="rules" label-placement="left" :label-width="100">
                    <NGrid responsive="screen" item-responsive>
                        <NFormItemGi span="24" label="权限组名称" path="name">
                            <NInput v-model:value="model.name" placeholder="请输入权限组名称" />
                        </NFormItemGi>
                        <NFormItemGi span="24" label="规则ID" path="rulesArray">
                            <NTreeSelect
                                v-model:value="model.rulesArray"
                                placeholder="请选择规则"
                                :options="rulesTree"
                                :loading="rulesLoading"
                                multiple
                                cascade
                                checkable
                                clearable
                            />
                        </NFormItemGi>
                        <NFormItemGi span="24 m:12" label="状态" path="status">
                            <NRadioGroup v-model:value="model.status">
                                <NRadio value="hidden" label="禁用" />
                                <NRadio value="normal" label="正常" />
                            </NRadioGroup>
                        </NFormItemGi>
                    </NGrid>
                </NForm>
            </NScrollbar>
            <template #footer>
                <NSpace justify="end" :size="16">
                    <NButton @click="visible = false">取消</NButton>
                    <NButton type="primary" @click="handleSubmit">确认</NButton>
                </NSpace>
            </template>
        </NModal>
    </div>
</template>

<style scoped></style>
